#ifndef __mid_link_h__
#define __mid_link_h__

#include "stdint.h"
#include "types.h"

//---------------------------------------------------------------------------------

typedef enum{
	LINK_FrameType_ACKBit		   = 0x80,  //bit7: is ack
	LINK_FrameType_EncryptBit	   = 0x40,  //bit6: is encrypt

	LINK_FrameType_HeartBeat       = 0x00,
	LINK_FrameType_Request         = 0x01,
	LINK_FrameType_Response        = 0x02,
	
	LINK_FrameType_Request_Enc     = (LINK_FrameType_Request  | LINK_FrameType_EncryptBit),
	LINK_FrameType_Response_Enc    = (LINK_FrameType_Response | LINK_FrameType_EncryptBit),

}link_frametype_t;


#define LINK_FrameLen_Max          256  //ָ�����֡���ȣ���λ �ֽ�
#define LINK_TxTimeout_Max         200  //ָ������֡ʱ�ȴ�ack�ĳ�ʱʱ������λms
#define LINK_TxRepeat_Max          3    //ָ������ط�����

#pragma anon_unions

// ����·��Ŀ��ڵ�
#define MASTER_MCU      0x01
#define SOC             0x02
#define BPILLAR_MCU     0x03
#define BODY_CAN		0x04

typedef union {
	struct {
		uint16_t code  :8; //major  minor
		uint16_t dest  :4;
		uint16_t src   :4;
	}op;
	uint16_t cmd;	
}cmd_opcode_t;

typedef enum{

	FrameAddrSrc_Mask		= 0xF0,
	FrameAddrSrc_MainMcu	= 0x10,
	FrameAddrSrc_SOC		= 0x20,
	FrameAddrSrc_BidMcu		= 0x30,
	FrameAddrSrc_BodyCan	= 0x40,

	FrameAddrDst_Mask       = 0x0F,
	FrameAddrDst_MainMcu	= 0x01,
	FrameAddrDst_SOC		= 0x02,
	FrameAddrDst_BidMcu		= 0x03,
	FrameAddrDst_BodyCan	= 0x04,
}link_frameaddr_t;


// ֡����
typedef union {
	struct {
		uint8_t frame_head_h;  //fix to 0x55
		uint8_t frame_head_l;  //fix to 0xAA
		
		uint8_t frame_len;     //total bin of the frame	
		uint8_t frame_number;  //
		uint8_t frame_type;    //referance @link_frametype_t
		uint8_t addr;
		uint8_t op;

		uint8_t msg[1];       //total bin must less then LINK_DATA_LEN_MAX
	};

	uint8_t bin[LINK_FrameLen_Max];	
}link_frame_t;


typedef enum{
	STLINK_RxHead = 0,
	STLINK_RxLen,
	STLINK_RxEnd
}link_rx_state_t;


typedef enum{
	STLINK_Reset,
	STLINK_WaitConnect,
	STLINK_TxIdle,
	STLINK_TxFrame,
	STLINK_WaitAck,
}link_srv_state_t;


typedef enum {
	LinkTxMsg_None, //֮ǰδ������Ϣ��
	LinkTxMsg_Busy,
	LinkTxMsg_Success, 
	LinkTxMsg_Failed,
} link_tx_result_t;

typedef struct{
	//֡����״̬��(�ڲ�ʹ��)
	link_rx_state_t rx_state;
	uint16_t        rx_count;  //�յ����ֽ���
	link_frame_t    rx_buffer;  //�յ������ݣ�����֡

	//״̬���������, ����ӿ�
	uint8_t         rx_ack_valid;
	link_frame_t    rx_ack_frame; //�����յ���ack֡(soc������mcu��ack)
	
	uint8_t         rx_msg_valid;
	link_frame_t    rx_msg_frame; //�����յ���msg֡ (soc������mcu��֡)

	uint8_t         rx_msg_valid_soc2can;
	link_frame_t    rx_msg_frame_soc2can; //�����յ���msg֡ (soc��������ģ���֡,���ϲ���ȡ������can��)
}link_rx_t;


typedef struct{
	//֡����״̬��
	link_srv_state_t state;
	uint8_t          state_enter;
	uint32_t         state_timer;

	//����Ҫ������msg֡
	uint8_t          tx_msg_valid;
	link_tx_result_t tx_result;
	uint8_t          tx_number;
	uint8_t          tx_repeat;
	link_frame_t     tx_msg_frame; //�������ڷ��͵�msg֡ 

    // send heartbeat & rec ack
    uint8_t tx_heartbeat_valid;
    uint8_t tx_heartbeat_number;	// ��������֡��

    uint8_t link_ok;
}link_private_t;

//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
//����ӿ�
void mid_link_initpin(void);
void mid_link_init(void);
void mid_link_deinit(void);
void mid_link_1ms_timer(void);
void mid_link_service(void);

uint8_t mid_link_getmsg(link_frametype_t * type, uint16_t * cmd, uint8_t* data[], uint8_t* data_len);
uint8_t mid_link_sendmsg_from_app(link_frametype_t type, uint16_t cmd, uint8_t data[], uint8_t data_len);

link_tx_result_t mid_link_getresult(void); //��ȡ���ͽ��
uint16_t mid_link_crc16_xmodem(uint8_t *bin, uint8_t bin_len);



#endif

